package fr.glre.tartopom;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class TourneunpeuActivity extends Activity implements
		SensorEventListener {

	private TextView tv1;
	private TextView tv2;
	private Button bouton;

	private float x;
	private float startX;
	private SensorManager sm;
	private PowerManager pm;
	PowerManager.WakeLock wl;

	private boolean wasInPrecisionZone;
	private double nbTour;

	private Handler handler321;
	private Handler handlerturn;
	private int compteur;

	private double goal;
	private int lvl;
	private int nbParties;

	private double[] lvlPrecTab = { 0.25, 0.15, 0.10, 0.05 };

	private Runnable troisdeuxungo = new Runnable() {
		@Override
		public void run() {
			if (compteur != 0) {
				tv2.setText("" + compteur);
				compteur--;

				handler321.postDelayed(this, 1000);
			} else {
				tv2.setText("Tournez !");

				start();

				compteur = 3;
				handlerturn.postDelayed(turning, 1000);
			}
		}
	};

	private Runnable turning = new Runnable() {
		@Override
		public void run() {
			if (compteur != 0) {
				compteur--;

				handler321.postDelayed(this, 1000);
			} else {
				double nbToursFin = nbTour;

				boolean reussi = getReussi(nbToursFin);

				if (reussi) {
					tv2.setText("Vous avez reussi !");
					nbParties++;
					if (nbParties % 5 == 0) {
						lvl++;
						tv2.setText("Vous avez reussi !\n\nPassage au niveau superieur !\n La precision recquise est maintenant de "
								+ lvlPrecTab[lvl] + "degres.");
					}
				} else {
					tv2.setText("Vous avez fait "
							+ Math.round(nbToursFin * 100.) / 100.
							+ "tours au lieu de " + goal + " tours");
				}

				initTextView();
				bouton.setVisibility(Button.VISIBLE);
			}
		}
	};

	public boolean getReussi(double nbToursFin) {

		if (Math.abs(nbToursFin - goal) < lvlPrecTab[lvl]) {
			return true;
		}
		return false;
	}

	private float getStartX() {
		return startX;
	}

	private float getX() {
		return x;
	}

	private void initTextView() {
		tv1.setText("Quand vous serez prêts, appuyez sur le bouton.");
	}

	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TO DO
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.tourneunpeu);

		sm = (SensorManager) getSystemService(SENSOR_SERVICE);
		sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION),
				SensorManager.SENSOR_DELAY_GAME);

		pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "resteaplat");
		wl.acquire();

		tv1 = (TextView) findViewById(R.id.tvtourne1);
		tv2 = (TextView) findViewById(R.id.tvtourne2);
		bouton = (Button) findViewById(R.id.btourne);

		initTextView();
		lvl = 0;
		start();

		bouton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				bouton.setVisibility(Button.INVISIBLE);

				goal = (Math.floor((Math.random() * 12.))) / 4.;

				tv1.setText("Vous devez faire tourner votre téléphone " + goal
						+ " fois.");
				tv2.setText("3");

				handler321 = new Handler();
				handlerturn = new Handler();

				compteur = 2;
				handler321.postDelayed(troisdeuxungo, 1000);
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.tourneunpeumenu, menu);

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.item1:
			Intent intent = new Intent(this.getBaseContext(),
					TournePomActivity.class);
			startActivity(intent);
			finish();
			break;
		case R.id.item2:
			Toast.makeText(
					this,
					"Posez le téléphone à plat sur une table,"
							+ " et appuyez sur le bouton \"C\'est parti !\". "
							+ "L'application vous indiquera un nombre de tour, et"
							+ " quand le compte à rebours sera terminé, tournez "
							+ "votre téléphone comme une toupie en essayant de faire "
							+ "exactement le nombre de tour demandés.",
					Toast.LENGTH_LONG).show();
			break;
		case R.id.item3:
			System.exit(RESULT_OK);
			break;
		}

		return false;
	}

	@Override
	public void onPause() {
		super.onPause();
		wl.release();
		sm.unregisterListener(this);
	}

	@Override
	public void onResume() {
		super.onResume();
		wl.acquire();
		sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION),
				SensorManager.SENSOR_DELAY_GAME);
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		int sensor = event.sensor.getType();
		float[] values = event.values;

		synchronized (this) {
			if (sensor == Sensor.TYPE_ORIENTATION) {
				setX(values[0]);
			}
		}
		nbTour = Math.floor(nbTour);
		double borneSup = (this.getStartX() + 10) % 360;
		if ((this.getX() > this.getStartX()) && (this.getX() < borneSup)) {
			if (!wasInPrecisionZone) {
				nbTour = nbTour + 1;
			}
			wasInPrecisionZone = true;
		} else {
			wasInPrecisionZone = false;
		}

		double decallage = ((this.getStartX() - this.getX()) / 360.);
		if (decallage < 0) {
			decallage = decallage + 1.;
		}
		nbTour = nbTour + decallage;
	}

	private void setStartX(float startX) {
		this.startX = startX;
	}

	private void setX(float x) {
		this.x = x;
	}

	// Saving the orientation at the start of the game
	public void start() {
		setStartX(getX());
		wasInPrecisionZone = true;
		nbTour = 0;
	}
}
